<template>
    <blank-layout>
        <div class="login-box">
            <div class="login-welcome" v-if="!showLogin">
                <!-- progress当前展示的数据，rate是总的数据 -->
                <!-- @click它是组件的自定义事件，click是可以添加修饰符--原生native -->
                <van-circle v-model="progress"
                    :rate="100"
                    size="40px"
                    :clockwise="false"
                    color="#ff5b02"
                    @click.native="closeTimer"
                    :text="(Math.ceil(progress / 20)) + 's'"/>

                    <!-- <van-circle v-model="progress" :rate="30" :speed="100" :text="'fdsfds'" /> -->

                <span class="title">凌动智能采购系统</span>
                <span class="sub">{{welText}}</span>
            </div>
            <div class="login-content" v-else>
                <span class="title">凌动智能采购系统</span>
                <div class="line">
                    <input type="text" v-model="loginObj.phone" placeholder="输入手机号">
                </div>
                <div class="line">
                    <input type="text" v-model="loginObj.vdtCode" placeholder="输入手机号">
                    <span @click="getVdtCode">{{vdtText}}</span>
                </div>
                <van-checkbox v-model="remember" checked-color="#ff5b02">是否记住手机号？</van-checkbox>
                <van-checkbox v-model="auto" checked-color="#ff5b02">是否免登录？</van-checkbox>
                <van-button block color="#ff5b02" @click="loginEvt">登录</van-button>
            </div>
            <span class="footer">design by qianfeng &copy; 2021-</span>
        </div>
    </blank-layout>
</template>

<script>
    import { AES, enc } from 'crypto-js'
    import { autoLoginApi, getVdtCodeApi, loginApi, userInfoApi } from '../../apis/loginApi'

    export default {

        data() {
            return {
                // 因为已进入欢迎页面，要开始免登录判断和数据请求，所以默认为loading
                autoFlag: 'loading',
                remember: false,
                auto: false,
                showLogin: false,
                progress: 100,
                welText: [
                    "一月，我听到了爆竹的声声催促",
                    "二月，我闻到了腊梅的缕缕幽香",
                    "三月，我看到了桃花绚烂如云霞",
                    "四月，我躺在了柳阴中酣然入梦",
                    "五月，我品尝着晶莹剔透的樱桃",
                    "六月，我观赏水莲花的绰约芳姿",
                    "七月，我跃入那清波荡漾的碧水",
                    "八月，置身于桂花雨中翩然起舞",
                    "九月，我漫步在飘满落叶的小径",
                    "十月，我欣然采摘那累累的硕果",
                    "十一月，我聆听冬天走来的步履",
                    "十二月，我掬起一捧洁白的雪花"
                ][new Date().getMonth()],
                loginObj: {
                    phone: '',
                    vdtCode: ''
                },
                timer: null,
                vdtText: '获取验证码'
            }
        },

        created() {
            this.loopTimer()

            // 判断是否有免登录
            this.autoLogin()
        },

        methods: {

            // 1、防止用户二次点击
            // 2、当倒计时没有完成的时候，点击不能发出请求，倒计时到了，用户又可以点击
            // 实现一个节流 -- 需要一个标识 可以使用按钮文字来实现这个标识
            async getVdtCode() {
                // 先判断是否在倒计时vdtText(重新获取(20s))，是否在请求数据（获取中...）
                if (this.vdtText !== '获取验证码') return

                // 去校验手机号
                if (!/^1[3-9]{1}[0-9]{9}$/.test(this.loginObj.phone)){
                    this.$toast({
                        message: '手机号输入错误',
                        position: 'bottom',
                    })
                    return
                }

                this.vdtText = '获取中...'

                let result = await getVdtCodeApi(this.loginObj.phone)
                if (result.code !== 200) {
                    this.$toast({
                        message: '获取验证码失败',
                        position: 'bottom',
                    })
                    this.vdtText = '获取验证码'
                    return
                }

                this.$toast.success(`验证码：${result.data.vdtCode}`)

                // 执行倒计时递归方法 -- 需要记录第一次调用时间
                this.loopVdtTimer(Date.now())
            },

            loopVdtTimer(st) {
                // 递归条件，否则递归式一个无限递归
                setTimeout(() => {
                    // 如何计算当前已经过去多少时间？方法的第一次调用时间被当前时间相减得到的时间差就是过去时间
                    // 因为是计算还剩余多少时间，总时间减去过去的时间
                    let _pt = 5 - Math.ceil((Date.now() - st) / 1000)
                    if (_pt > 0) {
                        this.vdtText = `重新获取(${_pt}s)`
                        this.loopVdtTimer(st)
                    } else {
                        // 用户又可以发送获取验证码 -- 修改标识
                        this.vdtText = '获取验证码'
                    }
                }, 200)
            },

            closeTimer() {
                if (this.autoFlag === 'loading') return
                if (this.autoFlag === 'home') {
                    this.$router.push('/home')
                } else {
                    this.showLogin = true
                }
                clearTimeout(this.timer)
            },

            // 系统自动登录业务
            async autoLogin() {
                // 获取自动登录的标识
                let flag = localStorage.getItem('auto-token')
                if (!!flag) {
                    // 因为免登录接口需要在请求头添加一个token标识，而Ajax封装方法本身会自动添加token数据
                    // 所以要先把token缓存到vuex，然后再发送请求
                    this.$store.commit('common/setToken', flag)

                    // 发送请求
                    let result = await autoLoginApi()

                    if (result.code === 200) {
                        this.$store.commit('common/setUser', result.data)

                        // 因为欢迎还在倒计时，这里广告时间还没有完成，所以不能直接跳转页面
                        this.autoFlag = 'home'
                    } else {
                        // 免登录失败，需要查看是否记住手机号
                        let phoneCache = localStorage.getItem('auto-phone')
                        if (!!phoneCache) {
                            this.loginObj.phone = AES.decrypt(phoneCache, 'asdfghjkl').toString(enc.Utf8)
                            this.remember = true
                        }

                        this.autoFlag = 'login'
                    }
                } else {
                    // 判断是否有记住手机号 -- 放在内存中的手机号加密后获取出来进行解密 -> AES 对称加密
                    let phoneCache = localStorage.getItem('auto-phone')
                    if (!!phoneCache) {
                        this.loginObj.phone = AES.decrypt(phoneCache, 'asdfghjkl').toString(enc.Utf8)
                        this.remember = true
                    }
                    
                    // 需要一个标识，免登录接口还在请求 -> 'loading'；如果接口调用成功--去首页 -> 'home'；如果失败--展示登录页面还有免登录标识不存在 -> 'login'
                    this.autoFlag = 'login'
                }
            },

            loopTimer() {
                this.timer = setTimeout(() => {
                    this.progress -= 1
                    if (this.progress > 0) {
                        this.loopTimer()
                    } else {
                        // 还要考虑免登录的问题？
                        if (this.autoFlag === 'home') {
                            this.$router.push('/home')
                        } else {
                            this.showLogin = true
                        }
                        
                    }
                }, 5 * 1000 / 100)
            },

            async loginEvt() {
                // 先校验数据，phone，验证码是否输入正确
                if (!/^1[3-9]{1}[0-9]{9}$/.test(this.loginObj.phone)) {
                    this.$toast('正确输入手机号')
                    return
                }

                if (!/^[0-9]{4}$/.test(this.loginObj.vdtCode)) {
                    this.$toast('正确输入验证码')
                    return
                }

                // 开始数据接口调用
                this.$toast.loading({
                    message: '登录中...',
                    forbidClick: true,
                    duration: 0
                })

                let result = await loginApi(this.loginObj)
                if (result.code !== 200) {
                    this.$toast('登录失败，请重试')
                    this.$toast.clear()
                    return
                }

                // 因为用户信息接口需要使用token所以要先缓存token，再请求接口
                this.$store.commit('common/setToken', result.data.token)
                // code: 403 message: "Request information authentication failed." 表示token数据错误
                // this.$store.commit('common/setToken', 'result.data.token')

                let user = await userInfoApi(result.data.id)
                // 系统中会一直使用用户信息，需要缓存到vuex中去
                this.$store.commit('common/setUser', user.data)

                // 判断用户是否记住手机号，用户是否同意自动登录
                if (this.remember) {
                    // 为了保护用户的手机号不被泄露，所以加密处理
                    localStorage.setItem('auto-phone', AES.encrypt(this.loginObj.phone, 'asdfghjkl').toString())
                } else {
                    localStorage.removeItem('auto-phone')
                }
                if (this.auto) {
                    // 为了保护用户的手机号不被泄露，所以加密处理
                    localStorage.setItem('auto-token', result.data.token)
                } else {
                    localStorage.removeItem('auto-token')
                }

                // 关闭加载框
                this.$toast.clear()

                // 在vuex中获取数据，不会造成线程阻塞
                this.$store.dispatch('common/rightsAct', user.data.role)

                // 首页跳转
                this.$router.push('/home')
            }
        }
    }
</script>

<style lang="less" scoped>
    @import "./index.less";
</style>